import { dom, Nodes } from '@knno/dom';
import { genId } from '../../tools/utils';
import { groupStyle } from './group.css';
import { Radio } from '../radio/radio';

export class Group extends Nodes {
	constructor() {
		super(dom.div(groupStyle));
		this.name(genId('group'));
	}

	override name(): string | null;
	override name(value: string | null): this;
	override name(value?: string | null): string | null | this {
		if (value === undefined) {
			return super.name();
		}
		const n = value || genId('group');
		super.name(n);
		this.query(`button[type=radio]`).attr('group', n);
		return this;
	}

	override append(...elem: (Text | Element | (Element | Text)[])[]): this {
		super.append(...elem);
		elem.forEach((e) => {
			if (e instanceof Radio) {
				e.group(this.name());
			}
		});
		return this;
	}

	override appendAll(nodes: (Nodes | Text)[]): this {
		super.appendAll(nodes);
		nodes.forEach((e) => {
			if (e instanceof Radio) {
				e.group(this.name());
			}
		});
		return this;
	}

	override insert(...elem: (Text | Element | (Element | Text)[])[]): this {
		super.insert(...elem);
		elem.forEach((e) => {
			if (e instanceof Radio) {
				e.group(this.name());
			}
		});
		return this;
	}

	override text(): string;
	override text(text: string): this;
	override text(text?: string): this | string | undefined {
		if (text === undefined) {
			return this.query(`button[type=radio][checked=true],button[type=check][checked=true]`)
				.map((b) => b.textContent)
				.join(',');
		}
		return this;
	}

	override value(): string[];
	override value(value: string[]): this;
	override value(value?: string[]): this | string[] {
		if (value === undefined) {
			return this.query(`button[type=radio][checked=true],button[type=check][checked=true]`)
				.map((b) => (b as HTMLButtonElement).value)
				.filter((v): v is string => v !== null);
		}
		this.query(`button[type=radio],button[type=check]`).forEach((b) => {
			if (value.includes((b as HTMLButtonElement).value)) {
				b.dispatchEvent(new CustomEvent('update', { detail: { checked: true } }));
			}
		});
		return this;
	}
}

export function group(...className: string[]) {
	return new Group().addClass(...className);
}
